package com.novoda.runbuddy.model;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;

import com.novoda.runbuddy.util.DateUtils;

public class PastJogsCalendar {

	Calendar								calendar;
	private LinkedHashMap<Integer, Integer>	daysinMonthTable;
	public final int						NO_OF_ROWS						= 5;
	public final int						NO_OF_COLS						= 6;
	private String							currShowingMonth;

	public static final String				SHOWING_DATE_FORMAT				= "MMM-yyyy";
	public static final String				CURRENT_DATE_IN_MONTH_FORMAT	= "d";

	public final static int					MONDAY_COL						= 0;
	public final static int					TUESDAY_COL						= 1;
	public final static int					WEDNESDAY_COL					= 2;
	public final static int					THURSDAY_COL					= 3;
	public final static int					FRIDAY_COL						= 4;
	public final static int					SATURDAY_COL					= 5;
	public final static int					SUNDAY_COL						= 6;
	private SimpleDateFormat				showingDateFormatter;
	private String							firstIndexOfWeekDay				= "00";

	public PastJogsCalendar() {
		calendar = new GregorianCalendar();
		daysinMonthTable = new LinkedHashMap<Integer, Integer>();
		showingDateFormatter = new SimpleDateFormat(SHOWING_DATE_FORMAT);
	}

	public void setCurrentMonthTable(int year, int month, int day) {
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DAY_OF_MONTH, day);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		int firstWeekdayOfMonth = getIndexOfFirstWeekDayOfMonth(calendar);
		int noOfDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

		setMonthText(showingDateFormatter.format(calendar.getTime()));
		setCellsInTheMonthTable(firstWeekdayOfMonth, noOfDays);
	}

	private void setMonthText(String month) {
		this.currShowingMonth = month;
	}

	protected int getIndexOfFirstWeekDayOfMonth(Calendar calendar) {
		int day = DateUtils.calcFirstOfMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH));

		if (day == 0) {
			day = 7;
		}

		return day;
	}

	public void setCellsInTheMonthTable(int firstWeekdayOfMonth, int maxNoOfDaysInMonth) {

		int currentCol = 0, currentRow = 0;
		Integer day = 1;
		String currentIndex = "00";

		setPaddingZerosInMonth(firstWeekdayOfMonth);

		for (; currentCol < firstWeekdayOfMonth - 1; currentCol++) {
			currentIndex = incrementIndex(currentIndex);
		}

		while (notInTheLastCellInTable(currentCol, currentRow)) {
			if (firstCellOfNewRow(currentCol)) {
				currentRow++;
				currentCol = 0;
				currentIndex = setIndex(currentRow, currentCol);
			}

			if (day <= maxNoOfDaysInMonth) {
				this.daysinMonthTable.put(new Integer(currentIndex), day);
			} else {
				this.daysinMonthTable.put(new Integer(currentIndex), 00);
			}

			day++;
			currentCol++;
			currentIndex = setIndex(currentRow, currentCol);
		}

	}

	private boolean firstCellOfNewRow(int currentCol) {
		return currentCol > NO_OF_COLS;
	}

	private boolean notInTheLastCellInTable(int currentCol, int currentRow) {
		return !(currentRow == NO_OF_ROWS && firstCellOfNewRow(currentCol));
	}

	private String incrementIndex(String currentIndex) {
		Integer indexRow = new Integer(String.valueOf(currentIndex.charAt(0)));
		Integer indexCol = new Integer(String.valueOf(currentIndex.charAt(1)));

		indexCol++;
		currentIndex = indexRow.toString() + indexCol.toString();
		return currentIndex;
	}

	private String setIndex(int currentRow, int col) {
		String currentIndex;
		String currCol = new String(Integer.toString(col));
		currentIndex = new String(currentRow + currCol);
		return currentIndex;
	}

	public long getCurrentlyShowingDate() {
		return calendar.getTimeInMillis();
	}

	public int get(int dateType) {

		switch (dateType) {
			case Calendar.DAY_OF_MONTH:
				return calendar.get(Calendar.DAY_OF_MONTH);
			case Calendar.MONTH:
				return calendar.get(Calendar.MONTH);
			case Calendar.YEAR:
				return calendar.get(Calendar.YEAR);
		}

		return 0;
	}

	public Calendar getCalendar() {
		return calendar;
	}

	public void setDaysInMonthTable(LinkedHashMap<Integer, Integer> tableOfDays) {
		this.daysinMonthTable = tableOfDays;
	}

	public LinkedHashMap<Integer, Integer> getDaysInMonthTable() {
		return this.daysinMonthTable;
	}

	public String getCurrentShowingMonth() {
		return currShowingMonth;
	}

	public void setPaddingZerosInMonth(Integer noOfZeros) {
		int currentCol = 0, currentRow = 0;
		String currentIndex = "00";

		for (; currentCol <= noOfZeros; currentCol++) {
			this.daysinMonthTable.put(new Integer(currentIndex), 00);
			currentIndex = setIndex(currentRow, currentCol);
		}

		currentIndex = setIndex(currentRow, currentCol);
		firstIndexOfWeekDay = currentIndex;
	}

	public String getFirstIndexOfWeekDay() {
		return firstIndexOfWeekDay;
	}

	public String getTableIndexOfDay(Integer dayOfMonth) {

		for (Iterator<Entry<Integer, Integer>> iter = daysinMonthTable.entrySet().iterator(); iter.hasNext();) {
			Entry<Integer, Integer> cell = iter.next();

			if (cell.getValue() == dayOfMonth) {

				if (cell.getKey() < 10) {
					return "0" + cell.getKey().toString();
				}

				return cell.getKey().toString();
			}
		}

		return null;
	}

}
